package session.stateless;

import javaclass.AES;
import entity.CRM.CustomerExecutive;
import java.util.List;
import javax.ejb.Stateless;
import entity.Employee;  
import entity.Position;
import entity.Role;
import javaclass.RandomString;
import javax.persistence.EntityManager; 
import javax.persistence.NoResultException; 
import javax.persistence.PersistenceContext; 
import javax.persistence.Query;

@Stateless
public class EmployeeBean implements EmployeeBeanLocal {

    @PersistenceContext (unitName = "M10-IS3102-ejbPU")
    private EntityManager entityManager; 

    //method to get employee object based on username
    @Override
    public Employee getEmployee(String userName){
        Query query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.userName = :inUserName"); 
        query.setParameter("inUserName", userName); 
 
        Employee employee = null; 
         
        try 
        { 
            employee = (Employee)query.getSingleResult(); 
        } 
        catch(NoResultException ex) 
        { 
            ex.printStackTrace(); 
        } 
        return employee;
    }
    
    //method to get employee id based on username
    @Override
    public Long getEmployeeId(String userName){
        Query query = entityManager.createQuery("SELECT e.employeeId FROM Employee e WHERE e.userName = :inUserName"); 
        query.setParameter("inUserName", userName); 
        Long employeeId = null; 
         
        try 
        { 
            employeeId = (Long)query.getSingleResult(); 
        } 
        catch(NoResultException ex) 
        { 
            //ex.printStackTrace(); 
        } 
        return employeeId;
    }

    //method to create new employee (including customerexecutive)
    @Override
    public long createNewEmployee(String username, String password, String employeeName, String employeeNRIC, String employeeEmail, String employeeContactNumber, String employeeAddress, Long attempt, boolean activatedStatus, long positionId, boolean deletedStatus){
        Query q = entityManager.createQuery("SELECT c FROM Role c WHERE c.id = 2");
        Role role = (Role) q.getSingleResult();
        
        Position position = entityManager.find(Position.class, positionId);
        if (position.getRoles().contains(role))
        {
            CustomerExecutive customerExecutive = new CustomerExecutive();
            String encryptedPassword = "";
            try{
                AES aes = new AES();
                RandomString rs = new RandomString();
                String modifiedPassword = customerExecutive.getEmployeeId() + ":" + password + ":" + rs.RandomStringWithLength(3);
                encryptedPassword = aes.encrypt(modifiedPassword);
            }   
            catch (Exception e){
            }
            customerExecutive.setUserName(username);
            customerExecutive.setPassword(encryptedPassword);
            customerExecutive.setEmployeeName(employeeName);
            customerExecutive.setEmployeeNRIC(employeeNRIC);
            customerExecutive.setEmployeeEmail(employeeEmail);
            customerExecutive.setEmployeeContactNumber(employeeContactNumber);
            customerExecutive.setEmployeeAddress(employeeAddress);
            customerExecutive.setAttempt(attempt);
            customerExecutive.setActivatedStatus(activatedStatus);
            customerExecutive.setDeletedStatus(deletedStatus);
            customerExecutive.setPosition(position);
            
            entityManager.persist(customerExecutive);
            return customerExecutive.getEmployeeId();
        }
        else
        {
            Employee employee = new Employee();
            String encryptedPassword = "";
            try{
                AES aes = new AES();
                RandomString rs = new RandomString();
                String modifiedPassword = employee.getEmployeeId() + ":" + password + ":" + rs.RandomStringWithLength(3);
                encryptedPassword = aes.encrypt(modifiedPassword);
            }   
            catch (Exception e){
            }
            employee.setUserName(username);
            employee.setPassword(encryptedPassword);
            employee.setEmployeeName(employeeName);
            employee.setEmployeeNRIC(employeeNRIC);
            employee.setEmployeeEmail(employeeEmail);
            employee.setEmployeeContactNumber(employeeContactNumber);
            employee.setEmployeeAddress(employeeAddress);
            employee.setAttempt(attempt);
            employee.setActivatedStatus(activatedStatus);
            employee.setDeletedStatus(deletedStatus);
            employee.setPosition(position);
            
            entityManager.persist(employee);
            return employee.getEmployeeId();
        }
    }

    //nmethod to find sepecific user with username and password, used for login
    @Override
    public Employee find(String userName, String password){
        System.out.println("employee find"+userName+""+password);
        Employee employee = this.getEmployee(userName); 
         
        if (employee == null) {
            return null; 
        }
        else 
        { 
            String decryptedPassword = "";
            try{
                AES aes = new AES();
                String employeePassword = employee.getPassword();
                decryptedPassword = aes.decrypt(employeePassword);
                decryptedPassword = decryptedPassword.split(":")[1];
            }
            catch (Exception e){
                
            }
            
            if(true){
            //If we want to change back the code to compare the original password    
            //if (employee.getPassword().equals(password)){
                return employee;
            }
            else 
            {
                return null;
                //return employee;
            }
            
        }
    }

    //method to get the whole list of employees in the database
    @Override
    public List<Employee> getEmployees() {
       Query query=entityManager.createQuery("SELECT p FROM Employee p WHERE p.deletedStatus=false");
       return query.getResultList();
    }
    
    //Update Employee method use for update/edit system users by adminstrator
    @Override
    public void updateEmployee(long employeeId, String username, String employeeName, String employeeNRIC, String employeeEmail, String employeeContactNumber, String employeeAddress, Long attempt, boolean activatedStatus, long positionId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        if (employee != null)         
        {
            employee.setUserName(username);
            employee.setEmployeeName(employeeName);
            employee.setEmployeeNRIC(employeeNRIC);
            employee.setEmployeeEmail(employeeEmail);
            employee.setEmployeeAddress(employeeAddress);
            employee.setEmployeeContactNumber(employeeContactNumber);
            employee.setActivatedStatus(activatedStatus);
            employee.setAttempt(attempt);
            
            Position position = entityManager.find(Position.class, positionId);
            employee.setPosition(position);
            
            entityManager.flush();       
        }
    }
    
    //Update Employee method use for update/edit user profile
    @Override
    public void updateEmployee(long employeeId, String employeeEmail, String employeeContactNumber, String employeeAddress){
        Employee employee = entityManager.find(Employee.class, employeeId);
        if (employee != null)         
        {
            
            employee.setEmployeeEmail(employeeEmail);
            employee.setEmployeeAddress(employeeAddress);
            employee.setEmployeeContactNumber(employeeContactNumber);
            
            entityManager.flush();       
        }
    }
    
    //update password for a specific user, used in employee's profile
    @Override
    public void updatePassword(long employeeId, String newPassword){
        Employee employee = entityManager.find(Employee.class, employeeId);
        if (employee != null)         
        {
            String encryptedPassword = "";
            try{
                AES aes = new AES();
                RandomString rs = new RandomString();
                String modifiedPassword = employee.getEmployeeId() + ":" + newPassword + ":" + rs.RandomStringWithLength(3);
                encryptedPassword = aes.encrypt(modifiedPassword);
            }
            catch(Exception e){
                
            }
            employee.setPassword(encryptedPassword);
            if (employee.getAttempt() == -1){
                employee.setAttempt((long)0);
            }
            entityManager.flush();       
        }       
    }
    
    //==============================================================================================
    //Under this section, there are methods to check access right of employee
    @Override
    public boolean isAdmin(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 1)
                    {
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isAdminViewable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 6){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isAdminCreatable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 7){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isAdminEditable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 8){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isAdminDeletable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 9){
                        System.out.println("isAdminDeletable");
                        return true;
                    }
                }
                return false;
            }
        }
    }
    
    @Override
    public boolean isCRMStaff(long employeeId){
         Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 2){
                        return true;
                    }
                }
                return false;
            }
        }       
    }

    @Override
    public boolean isCRMStaffViewable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 10){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isCRMStaffCreatable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 11){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isCRMStaffEditable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 12){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isCRMStaffDeletable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 13){
                        return true;
                    }
                }
                return false;
            }
        }
    }    
    
    @Override
    public boolean isFRMStaff(long employeeId){
         Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 3){
                        return true;
                    }
                }
                return false;
            }
        }       
    }    
    
    @Override
    public boolean isFRMStaffViewable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 14){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isFRMStaffCreatable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 15){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isFRMStaffEditable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 16){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isFRMStaffDeletable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 17){
                        return true;
                    }
                }
                return false;
            }
        }
    }    
        
    @Override
    public boolean isMRPStaff(long employeeId){
         Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 4){
                        return true;
                    }
                }
                return false;
            }
        }       
    }    

    @Override
    public boolean isMRPStaffViewable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 18){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isMRPStaffCreatable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 19){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isMRPStaffEditable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 20){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isMRPStaffDeletable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 21){
                        return true;
                    }
                }
                return false;
            }
        }
    }    
    
     @Override
    public boolean isSCMStaff(long employeeId){
         Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 5){
                        return true;
                    }
                }
                return false;
            }
        }       
    }

    @Override
    public boolean isSCMStaffViewable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 22){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isSCMStaffCreatable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 23){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isSCMStaffEditable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 24){
                        return true;
                    }
                }
                return false;
            }
        }
    }

    @Override
    public boolean isSCMStaffDeletable(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        Position p = employee.getPosition();
        if (p == null){
            return false;
        }
        else{
            List<Role> roles = (List)p.getRoles();
            if (roles.isEmpty()){
                return false;
            }
            else{
                for (Role r:roles){
                    if (r.getId() == 25){
                        return true;
                    }
                }
                return false;
            }
        }
    }    

    @Override
    public boolean isFirstLogin(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        if (employee.getAttempt() == -1){
            return true;
        }
        return false;
    }        
         
//==============================================================================
    
     @Override
     public void deleteEmployee(long employeeId){
        Employee employee = entityManager.find(Employee.class, employeeId);
        if (employee != null)         
        {
            employee.setDeletedStatus(true);
            entityManager.flush();       
        }   
    }
    
    @Override
    public void addContactList(long employeeId, long friendId){
        System.out.println("Add Contact List");
        Employee employee = entityManager.find(Employee.class, employeeId);
        Employee friend = entityManager.find(Employee.class, friendId);

        employee.getContactList().add(friend);
        entityManager.flush();

        System.out.println(employee.getContactList().size());
    }
    
    @Override
    public void removeContactList(long employeeId, long friendId){
        System.out.println("Add Contact List");
        Employee employee = entityManager.find(Employee.class, employeeId);
        Employee friend = entityManager.find(Employee.class, friendId);
        employee.getContactList().remove(friend);
        entityManager.flush();
    }

    @Override
    public void updateWrongLogin(String userName){
        Employee employee = this.getEmployee(userName);
        if (employee != null){
            employee.setAttempt(employee.getAttempt() + 1);
            if (employee.getAttempt() >= 3){
                employee.setActivatedStatus(false);
            }
            entityManager.flush();
        }
    }
    
    //method to reset password by admin
    @Override
    public void resetPassword(long employeeId, String newPassword){
        Employee employee = entityManager.find(Employee.class, employeeId);
        if (employee != null)         
        {
            String encryptedPassword = "";
            try{
                AES aes = new AES();
                RandomString rs = new RandomString();
                String modifiedPassword = employee.getEmployeeId() + ":" + newPassword + ":" + rs.RandomStringWithLength(3);
                encryptedPassword = aes.encrypt(modifiedPassword);
            }
            catch(Exception e){
                
            }
            employee.setPassword(encryptedPassword);
            employee.setAttempt((long)-1);
            entityManager.flush();       
        }       
    }
}
